package com.xiaominfo.oss.sdk.upload.handle;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.util.BeanUtil;
import com.xiaominfo.oss.sdk.OSSClientProperty;
import com.xiaominfo.oss.sdk.client.FileBytesResponse;
import com.xiaominfo.oss.sdk.common.OSSClientMessage;
import com.xiaominfo.oss.sdk.upload.IUpload;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.List;

/**
 * @description 用formData上传（适合大文件，但是性能一般）
 * @auther 蔡龙
 * @create 2019-09-27 11:21
 */
public class FormDataUploadHandle implements IUpload {
    //验证md5接口
    private static final String VERIFICATION_MD5 = "/oss/material/fileVerify";

    public OSSClientProperty ossClientProperty;

    public FormDataUploadHandle(OSSClientProperty ossClientProperty) {
        this.ossClientProperty = ossClientProperty;
    }
    @Override
    public OSSClientMessage<FileBytesResponse> upload(File file) throws UnsupportedEncodingException {
        OSSClientMessage<FileBytesResponse> ossClientMessage = new OSSClientMessage<>();
        //获取文件原始名称
        String originalName = file.getName();
        String mediaType = "unkown";
        int idx = originalName.lastIndexOf(".");
        if (idx > 0) {
            mediaType = originalName.substring(idx + 1);
        }
        MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        builder.setCharset(Charset.forName("UTF-8")).addBinaryBody("file", file, ContentType.MULTIPART_FORM_DATA, originalName)
                .addPart("appsecret", new StringBody(ossClientProperty.getAppsecret(), Charset.forName("UTF-8")))
                .addPart("project", new StringBody(ossClientProperty.getProject(), Charset.forName("UTF-8")))
                .addPart("appid", new StringBody(ossClientProperty.getAppid(), Charset.forName("UTF-8")));
        return run(builder,ossClientProperty.getRemote());
    }

    private HttpPost getHttpPost(MultipartEntityBuilder builder,String url){
        HttpPost request = new HttpPost(url);
        HttpEntity httpEntity = builder.build();
        request.setEntity(httpEntity);
        return request;
    }

    private OSSClientMessage run(MultipartEntityBuilder builder,String url){
        OSSClientMessage<FileBytesResponse> responseOSSClientMessage = new OSSClientMessage<>();
        try {
            CloseableHttpClient client = HttpClients.createDefault();
//
            HttpPost request = this.getHttpPost(builder,url);
            CloseableHttpResponse httpResponse = client.execute(request);
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                String content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
                OSSClientMessage ossClientMessage = JSON.toJavaObject(JSON.parseObject(content), OSSClientMessage.class);

                Object data = ossClientMessage.getData();
                if(data instanceof JSONArray){
                    List<FileBytesResponse> fileBytesResponse = JSONArray.parseArray(JSON.toJSONString(data), FileBytesResponse.class);
                    if (fileBytesResponse != null && fileBytesResponse.size() > 0) {
                        ossClientMessage.setData(fileBytesResponse.get(0));
                    }
                }
                if(data instanceof JSONObject){
                    FileBytesResponse fileBytesResponse = new FileBytesResponse();
                    BeanUtils.copyProperties(fileBytesResponse,data);
                    ossClientMessage.setData(fileBytesResponse);
                }
                return ossClientMessage;
            }
        }catch (Exception e){
            handleServerExceptionMessage(responseOSSClientMessage, e);
        }
        return responseOSSClientMessage;
    }

    @Override
    public OSSClientMessage<FileBytesResponse> verificationMD5(String md5) throws UnsupportedEncodingException {
        MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        builder.setCharset(Charset.forName("UTF-8")).addPart("md5",new StringBody(md5, Charset.forName("UTF-8")))
                .addPart("appsecret", new StringBody(ossClientProperty.getAppsecret(), Charset.forName("UTF-8")))
                .addPart("project", new StringBody(ossClientProperty.getProject(), Charset.forName("UTF-8")))
                .addPart("appid", new StringBody(ossClientProperty.getAppid(), Charset.forName("UTF-8")));
        return run(builder,ossClientProperty.getOriginalUrl() + VERIFICATION_MD5);
    }

    private void handleServerExceptionMessage(OSSClientMessage ossClientMessage, Exception e) {
        ossClientMessage.setCode("8500");
        ossClientMessage.setMessage(e.getMessage());
    }
}
